#ifndef __KCP_SERVER_H__
#define __KCP_SERVER_H__

#include "eventloop.h"

#include "ikcp.h"

#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

#include <functional>
#include <vector>

#include "kcp_server_context.h"

namespace Gazella {

typedef std::function<void(const std::string&, const KcpServerContext*)> kcp_server_recv_cb_t;

class KcpServer {
public:
    KcpServer();
    ~KcpServer();

    bool init(uint32_t conv, const std::string& local_ip, const int local_port);

    void send_message(const std::string& message); //send to all
    void send_message(const std::string& message, const KcpServerContext* kcpserver_context);

    void set_recv_cb(kcp_server_recv_cb_t cb);

private:
    void __ikcp_update_timer_callback(ev::timer& w, int revents);
    void __udp_recv_callback(ev::io& w, int revents);

    bool __create_udp_server(const std::string& local_ip, const int local_port);

    KcpServerContext* __get_kcpserver_context(const struct sockaddr_in& caddr);

private:
    int m_sd;
    struct sockaddr_in m_saddr;

    uint32_t m_conv;

    ev::timer m_timer;
    ev::io m_rx_io;

    kcp_server_recv_cb_t m_kcp_recv_cb;

    //BUG: no kcpserver context deletion detection strategy 
    std::vector<KcpServerContext*> m_kcpserver_contexts;
};
}

#endif